diff --git a/lib/filelib.php b/lib/filelib.php
index 2aa0560cd73..7df1d8731fe 100644
--- a/lib/filelib.php
+++ b/lib/filelib.php
@@ -5305,6 +5305,9 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null, $offlin
         send_file_not_found();
 
     // ========================================================================================================================
+    } else if ($component === 'editor') {
+        require_once($CFG->libdir . '/filelib.php');
+        core_editor_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, $sendfileoptions);
     } else if (strpos($component, '_') === false) {
         // all core subsystems have to be specified above, no more guessing here!
         send_file_not_found();
@@ -5327,3 +5330,43 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null, $offlin
     }
 
 }
+
+/**
+ * Serves plugin files related to the MoodleQuickForm_editor content.
+ *
+ * @param stdClass $course the course object
+ * @param stdClass $cm the course module object
+ * @param stdClass $context the context
+ * @param string $filearea the name of the file area
+ * @param array $args extra arguments (itemid, path)
+ * @param bool $forcedownload whether or not force download
+ * @param array $options additional options affecting the file serving
+ * @return bool false if the file not found, just send the file otherwise and do not return anything
+ */
+function core_editor_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
+    if ($context->contextlevel != CONTEXT_USER) {
+        send_file_not_found();
+    }
+
+    if ($filearea !== 'frozen') {
+        send_file_not_found();
+    }
+
+    require_login($course, false, $cm);
+
+    $itemid = (int)array_shift($args);
+    $filename = array_pop($args);
+    if (!$args) {
+        $filepath = '/';
+    } else {
+        $filepath = '/' . implode('/', $args) . '/';
+    }
+
+    $fs = get_file_storage();
+    $file = $fs->get_file($context->id, 'editor', $filearea, $itemid, $filepath, $filename);
+    if (!$file) {
+        send_file_not_found();
+    }
+
+    send_stored_file($file, 0, 0, $forcedownload, $options);
+}
diff --git a/lib/form/editor.php b/lib/form/editor.php
index 8106a9994d6..d65d9d0702f 100644
--- a/lib/form/editor.php
+++ b/lib/form/editor.php
@@ -254,7 +254,7 @@ class MoodleQuickForm_editor extends HTML_QuickForm_element implements templatab
      * @return string Text content
      */
     public function get_text(): string {
-        return $this->_values['text'];
+        return $this->_values['text'] ?? '';
     }
 
     /**
@@ -507,7 +507,27 @@ class MoodleQuickForm_editor extends HTML_QuickForm_element implements templatab
      * @return string
      */
     public function getFrozenHtml(): string {
-        return format_text($this->get_text(), $this->getFormat()) . $this->_getPersistantData();
+        global $USER;
+
+        $options = (object)[
+            'overflowdiv' => true,
+        ];
+
+        $context = context_user::instance($USER->id);
+        $pattern = '/draftfile\.php\/\d+\/user\/draft\/(\d+)\/([^\/]+)/';
+        $text = $this->get_text();
+
+        if (preg_match_all($pattern, $text, $matches)) {
+            foreach ($matches[1] as $index => $draftitemid) {
+                file_save_draft_area_files($draftitemid, $context->id, 'editor', 'frozen',
+                    $draftitemid, ['subdirs' => false]);
+                $text = file_rewrite_urls_to_pluginfile($text, $draftitemid);
+                $text = file_rewrite_pluginfile_urls($text, 'pluginfile.php', $context->id, 'editor',
+                    'frozen', $draftitemid);
+            }
+        }
+
+        return format_text($text, $this->getFormat(), $options) . $this->_getPersistantData();
     }
 
     /**
diff --git a/lib/form/tests/editor_test.php b/lib/form/tests/editor_test.php
new file mode 100644
index 00000000000..d34a07b9a44
--- /dev/null
+++ b/lib/form/tests/editor_test.php
@@ -0,0 +1,201 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+namespace core_form;
+
+use context_user;
+use moodleform;
+use moodle_url;
+use MoodleQuickForm_editor;
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->libdir . '/form/editor.php');
+require_once($CFG->libdir . '/formslib.php');
+
+/**
+ * Unit tests for MoodleQuickForm_editor
+ *
+ * Contains test cases for testing MoodleQuickForm_editor
+ *
+ * @package    core_form
+ * @copyright  2023 Monash University (https://monash.edu/)
+ * @author     Trisha Milan <trishamilan@catalyst-au.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class editor_test extends \advanced_testcase {
+
+    protected function create_draftfileurl_and_pluginfileurl_from_sample_image() {
+        global $USER, $CFG;
+
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        $usercontext = context_user::instance($USER->id);
+        $fs = get_file_storage();
+        $filerecord = array(
+            'contextid' => $usercontext->id,
+            'component' => 'user',
+            'filearea'  => 'draft',
+            'itemid'    => file_get_unused_draft_itemid(),
+            'filepath'  => '/',
+            'filename'  => 'black.png'
+        );
+        $pngdata = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=');
+        $fs->create_file_from_string($filerecord, $pngdata);
+
+        return [
+            moodle_url::make_draftfile_url($filerecord['itemid'], $filerecord['filepath'], $filerecord['filename'])->out(),
+            $CFG->wwwroot . '/pluginfile.php/' . $usercontext->id . '/editor/frozen/' . $filerecord['itemid'] . '/black.png'
+        ];
+    }
+
+    /**
+     * Tests the getFrozenHtml() method with different input scenarios and text formats.
+     *
+     * @dataProvider getfrozenhtml_provider
+     * @param array $editorconfig An array containing config to be set in the editor.
+     * @param string $expectedoutput The expected output of the getFrozenHtml().
+     */
+    public function test_getFrozenHtml($editorconfig, $expectedoutput) {
+        global $USER;
+
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        list($draftfileurl, $pluginfileurl) = $this->create_draftfileurl_and_pluginfileurl_from_sample_image();
+        $editorconfig['text'] = str_replace('[draftfileurl]', $draftfileurl, $editorconfig['text']);
+        $expectedoutput = str_replace('[pluginfileurl]', $pluginfileurl, $expectedoutput);
+
+        $form = new test_editor_form();
+        $data['editorfield'] = $editorconfig;
+        $form->set_data($data);
+
+        // Simulate the process of saving the content.
+        $mform = $form->get_mform();
+        if ($form->is_submitted() && $form->is_validated()) {
+            $data = $form->get_data();
+            // Verify that the saved content matches the text and draftfile url.
+            $this->assertEquals($editorconfig['text'], $data->editorfield['text']);
+        }
+
+        // Freeze the editor element.
+        $mform->getElement('editorfield')->freeze();
+
+        // Verify that the saved content matches the text and pluginfile url.
+        $frozenhtml = $mform->getElement('editorfield')->getFrozenHtml();
+        $this->assertEquals($expectedoutput, $frozenhtml);
+    }
+
+    /**
+     * Data provider for the test_getfrozenhtml testcase.
+     *
+     * @return array of testcases (string)testcasename => [(array)editorconfig, (string)expectedoutput]
+     */
+    public function getfrozenhtml_provider() {
+        return [
+            'FORMAT_HTML with simple text' => [
+                [
+                    'text' => '<p>Hello world!</p>',
+                    'format' => FORMAT_HTML
+                ],
+                '<div class="no-overflow"><p>Hello world!</p></div>',
+            ],
+            'FORMAT_HTML with images' => [
+                [
+                    'text' => 'Embedded file <img src="[draftfileurl]" alt="black.png" />' .
+                        ' External image <img src="https://www.example.com/external.jpg" alt="external.jpg" />',
+                    'format' => FORMAT_HTML,
+                ],
+                '<div class="no-overflow">Embedded file <img src="[pluginfileurl]" alt="black.png" />' .
+                ' External image <img src="https://www.example.com/external.jpg" alt="external.jpg" /></div>',
+            ],
+            'FORMAT_MOODLE with simple text' => [
+                [
+                    'text' => '<p>Hello world!</p>',
+                    'format' => FORMAT_MOODLE
+                ],
+                '<div class="no-overflow"><div class="text_to_html"><p>Hello world!</p></div></div>',
+            ],
+            'FORMAT_MOODLE with images' => [
+                [
+                    'text' => 'Embedded file <img src="[draftfileurl]" alt="black.png">' .
+                        ' External image <img src="https://www.example.com/external.jpg" alt="external.jpg">',
+                    'format' => FORMAT_MOODLE,
+                ],
+                '<div class="no-overflow"><div class="text_to_html">Embedded file <img src="[pluginfileurl]" alt="black.png" />' .
+                ' External image <img src="https://www.example.com/external.jpg" alt="external.jpg" /></div></div>',
+            ],
+            'FORMAT_MARKDOWN with simple text' => [
+                [
+                    'text' => 'Hello *world*!',
+                    'format' => FORMAT_MARKDOWN
+                ],
+                '<div class="no-overflow"><p>Hello <em>world</em>!</p>' . "\n" . '</div>',
+            ],
+            'FORMAT_MARKDOWN with images' => [
+                [
+                    'text' => 'Embedded file ![black.png]([draftfileurl])' .
+                        ' External image ![external.jpg](https://www.example.com/external.jpg)',
+                    'format' => FORMAT_MARKDOWN,
+                ],
+                '<div class="no-overflow"><p>Embedded file <img src="[pluginfileurl]" alt="black.png" />' .
+                ' External image <img src="https://www.example.com/external.jpg" alt="external.jpg" /></p>' . "\n" . '</div>',
+            ],
+            'FORMAT_PLAIN with simple text' => [
+                [
+                    'text' => 'Hello world!',
+                    'format' => FORMAT_PLAIN
+                ],
+                '<div class="no-overflow">Hello world!</div>',
+            ],
+            'FORMAT_PLAIN with link' => [
+                [
+                    'text' => "Hello world! [draftfileurl]",
+                    'format' => FORMAT_PLAIN
+                ],
+                '<div class="no-overflow">Hello world! [pluginfileurl]</div>',
+            ],
+        ];
+    }
+}
+
+/**
+ * Form object to be used in test case.
+ */
+class test_editor_form extends moodleform {
+    /**
+     * Form definition.
+     */
+    public function definition() {
+        $mform = $this->_form;
+
+        $editoroptions = array('trusttext' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'subdirs' => false);
+        $mform->addElement('editor', 'editorfield', 'Simple label', null, $editoroptions);
+    }
+
+    /**
+     * Returns form reference.
+     *
+     * @return \MoodleQuickForm
+     */
+    public function get_mform() {
+        // Set submitted flag, to simulate submission
+        $this->_form->_flagSubmitted = true;
+        return $this->_form;
+    }
+}
